home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 415_02 / rtti / include / rtti.h < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-04  |  5.9 KB  |  180 lines

  1. #ifndef   _H_RTTI
  2. #define   _H_RTTI
  3.  
  4. /* %Z%%I%       %G% %U% %W% */
  5. /*
  6.  * COMPONENT_NAME: (COMINC) Common Header File for RTTI
  7.  *
  8.  * ORIGINS: 27
  9.  *
  10.  * (C) COPYRIGHT International Business Machines Corp. 1992
  11.  * This work was supported by a grant from International Business
  12.  * Machines, Inc. These procedures are contributed to the public domain
  13.  * by International Business Machines Inc. "AS IS" without any warranty
  14.  * of any kind including the warranty of merchantability or fitness
  15.  * for a particular purpose.
  16.  *
  17.  *
  18.  * This is free software. Feel free to redistribute and/or modify it.
  19.  * Please send us e-mail and let us know if you have any problems
  20.  * or suggestions.
  21.  *
  22.  * Arindam Banerji
  23.  * axb@cse.nd.edu
  24.  *
  25.  *
  26.  */
  27.  
  28.  
  29. // rtti.h
  30. // This file includes the definition of the RTTI interface as specified
  31. // by Stousroup. The implementation is portable to any compiler. If
  32. // your compiler supports exceptions, then define the variable exceptions
  33. // thru a -DEXCEPTIONS clause to your preprocessor. The additional
  34. // implementation information for this may be found in rttiimpl.h. The
  35. // actual implementation code may be found in rtti.c in the source
  36. // directory. Additions to this to support dynamic modification of type
  37. // type information, will be added later on.
  38.  
  39. #include   <string.h>
  40.  
  41. #ifndef   _KERNEL
  42. #include    <stdlib.h>
  43. #endif // _KERNEL
  44. /***********
  45.    BASIC   RTTI    INTERFACE
  46. **********/
  47.  
  48. // The following are the macro definitions that form the RTTI interface
  49. #define  static_type_info(T)     T::info()
  50. #define  ptr_type_info(p)        ((p)->get_info())
  51. #define  ref_type_info(r)        ((r).get_info() )
  52.  
  53. #define   GET_PTR_INFO(p)    ((p->get_info()).get_type_info())
  54. #define   GET_TYPE_INFO(T)    ((T::info()).get_type_info())
  55. #define   GET_TYPE_INFO_2(N,I1,I2)    ((N<I1,I2>::info()).get_type_info())
  56. #define GET_TYPE_INFO_3(N,I1,I2,I3)  ((N<I1,I2,I3>::info()).get_type_info())
  57.  
  58. /*
  59. #define  ptr_cast(T,p)      \
  60. (((T::info()).get_type_info())->can_cast(((p)->get_info()).get_type_info())\
  61.              ?     (void *) (p) :   0)  \
  62. */
  63.  
  64.  
  65. #define  ptr_cast(T,p) \
  66.     ((GET_TYPE_INFO(T))->can_cast(GET_PTR_INFO(p)) ? (void *) p : 0 ) \
  67.  
  68. #define  ptr_cast_2(N,I1,I2,p) \
  69.  ((GET_TYPE_INFO_2(N,I1,I2))->can_cast(GET_PTR_INFO(p)) ? (void *) p : 0 ) \
  70.  
  71. #define  ptr_cast_3(N,I1,I2,I3,p) \
  72. ((GET_TYPE_INFO_3(N,I1,I2,I3))->can_cast(GET_PTR_INFO(p)) ? (void *)p : 0) \
  73.  
  74.  
  75. #ifdef    EXCEPTIONS
  76. // use this part only if your compiler supports exceptions
  77. class   Bad_cast {
  78.     public :
  79.         Bad_cast(const char *p) : tn(p) { } ;
  80.         const char *cast_to() { return tn ; } ;
  81.     private :
  82.         const char *tn ;
  83.  } ; // specification for the exception class that handles inproper ref. casts
  84.  
  85. #define  ref_cast(T,r)    \
  86.       (T::info()->can_cast((r).get_info()) \
  87.            ? 0  : throw Bad_cast(T::info()->name()), (T&) (r) )
  88.  
  89. #endif    // EXCEPTIONS handled by the compiler
  90.  
  91.  
  92. /************
  93.    CLASS DEFINITIONS FOR RTTI INTERFACE
  94. ************/
  95.  
  96. // This class is used to separate the implmentation of the Type_info class
  97. // from its use. Thus, most of the macros may be reused, even if the imple-
  98. // mentation of the Type_info class changes.
  99. class  typeid {
  100.             friend   class Type_info ;  // Let the Type_info class have access
  101.   public :
  102.            typeid (const Type_info *p) : id(p) { } ; // just hold a pointer
  103.        const Type_info *get_type_info ( ) const
  104.           { return id ; } ;
  105.            int   operator== (typeid ) const ;
  106.   private :
  107.             const  Type_info    *id ;
  108.   } ; // specfication for the typeid class
  109.  
  110. extern int class_count ;
  111.  
  112. // This rightfully does not belong in this file, but due to the recursive
  113. // nature of the rtti stuff, it has to be put in this file.
  114. class   CLASS
  115.    {
  116.      public  :
  117.     CLASS() { } ;
  118.     virtual ~CLASS () { } ;
  119.        // scaffolding that is a prt of every RTTI user class
  120.     static  const hndl_recursion info_obj ;
  121.     virtual typeid get_info() const ;
  122.     static  typeid  info() ;
  123.     virtual void *get_this_ptr(void) const { return (void *)this ; }
  124.    } ;
  125.  
  126. class   base_iterator ;  // a forward declaration to keep compilers happy
  127.  
  128. // The following is the main class of the RTTI interface. It supports most
  129. // of the member functions needd to support the interface. In addition, it
  130. // itself uses the scaffolding necessary to generate run-time type
  131. // information. Hence, it itself may be inherited from to add more
  132. // functionality.
  133.  
  134. class  Type_info : public virtual CLASS {
  135.        friend  class  base_list ;
  136.  public  :
  137.    Type_info ( const char *name, const Type_info *bases[] )
  138.      : n(name), b(bases)
  139.       {  } ;
  140.    virtual ~Type_info()
  141.      {  }
  142.    const char *name () const { return n ; }  ;
  143.    base_iterator  bases(int direct= 0 ) const ;
  144.    int same ( const Type_info *p) const
  145.             { return ((this == p ) || (strcmp(n,p->n) == 0 )) ; }
  146.    int   has_base (const Type_info *, int direct = 0 ) const ;
  147.    int   can_cast ( const Type_info *p) const
  148.         {  return (same(p) || p->has_base(this)) ; }
  149.  
  150.    // scaffolding that is a prt of every RTTI user class, including this one
  151.    static  const Type_info info_obj ;
  152.    virtual typeid get_info() const ;
  153.    static  typeid  info() ;
  154.    static  Type_info  *_narrow(CLASS *) ;
  155.    virtual void *get_this_ptr(void) const ;
  156. #ifndef   _KERNEL
  157.    void  display(void) const  { cerr << n << endl ; }
  158. #endif  // _KERNEL
  159.  private :
  160.     const char *n ; // name of the class
  161.     const Type_info **b ; // list of bases
  162. } ; // end of the Type_info class specification
  163.  
  164. // The base iterator is used to loop thru the various bases of a class. This
  165. // list of base if set up with the direct set, then lists only the direct
  166. // base classes - otherwise, it lists all the base classes.
  167. class   base_iterator {
  168. public :
  169.      const Type_info *operator() () ;
  170.      void  reset () { i = 0 ; } ;
  171.      base_iterator ( const Type_info **b, int direct = 0 ) ;
  172.      ~base_iterator()  ;
  173. private :
  174.       short   i ;
  175.       short   alloc ;
  176.       const Type_info **b ;
  177. } ; // implementation specific base_iterator class specification
  178.  
  179. #endif   // _H_RTTI
  180.